﻿using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.Authorization;
using Abp.Authorization.Roles;
using Abp.Domain.Uow;
using Abp.Localization;
using Abp.Runtime.Caching;
using Abp.UI;
using Abp.Zero.Configuration;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using ARchGL.Platform.Authorization.Users;
using Abp.Domain.Repositories;
using Abp.Authorization.Users;
using System;

namespace ARchGL.Platform.Authorization.Roles
{
    /// <summary>
    /// Role manager.
    /// Used to implement domain logic for roles.
    /// </summary>
    public class RoleManager : AbpRoleManager<Role, User>
    {
        private readonly ILocalizationManager _localizationManager;
        private readonly IRepository<UserRole, long> userRoleRepository;

        public RoleManager(
            RoleStore store,
            IEnumerable<IRoleValidator<Role>> roleValidators,
            ILookupNormalizer keyNormalizer,
            IdentityErrorDescriber errors,
            ILogger<RoleManager> logger,
            IPermissionManager permissionManager,
            IRoleManagementConfig roleManagementConfig,
            ICacheManager cacheManager,
            IUnitOfWorkManager unitOfWorkManager,
            ILocalizationManager localizationManager,            
            IRepository<UserRole, long> _userRoleRepository)
            : base(
                store,
                roleValidators,
                keyNormalizer,
                errors,
                logger,
                permissionManager,
                cacheManager,
                unitOfWorkManager,
                roleManagementConfig)
        {
            _localizationManager = localizationManager;
            userRoleRepository = _userRoleRepository;
        }

        /// <summary>
        /// 获取角色信息
        /// </summary>
        /// <param name="id">角色标识</param>
        /// <returns></returns>
        public async Task<Role> GetByIdAsync(Guid id)
        {
            return null; // await Roles.FirstOrDefaultAsync(x => x.PrimaryId == id);
        }

        /// <summary>
        /// 获取指定用户角色信息
        /// </summary>
        /// <param name="id">用户标识</param>
        /// <returns></returns>
        public async Task<Role> GetRoleInfoByUserId(long id)
        {
            var query = from r in Roles
                        join ur in userRoleRepository.GetAll() on r.Id equals ur.RoleId into urJoined
                        from ur in urJoined.DefaultIfEmpty()
                        where ur.UserId == id
                        select r;
            return await Task.FromResult(query.FirstOrDefault());
        }

        public override Task SetGrantedPermissionsAsync(Role role, IEnumerable<Permission> permissions)
        {
            CheckPermissionsToUpdate(role, permissions);

            return base.SetGrantedPermissionsAsync(role, permissions);
        }

        private void CheckPermissionsToUpdate(Role role, IEnumerable<Permission> permissions)
        {
            if (role.Name == StaticRoleNames.Host.Admin &&
                (!permissions.Any(p => p.Name == AppPermissions.Pages_Administration_Roles_Edit) ||
                 !permissions.Any(p => p.Name == AppPermissions.Pages_Administration_Users_ChangePermissions)))
            {
                throw new UserFriendlyException(L("YouCannotRemoveUserRolePermissionsFromAdminRole"));
            }
        }

        private new string L(string name)
        {
            return _localizationManager.GetString(HostConsts.LocalizationSourceName, name);
        }
    }
}